#include "queue.h"
#include "logger.h"
int IsEmpty(Queue Q)
{
    return Q->Size == 0;
}

void MakeEmpty(Queue Q)
{
    Q->Size = 0;
    Q->Front = 1;
    Q->Rear = 0;
}

int IsFull(Queue Q)
{
    return Q->Size == Q->Capacity;
}

Queue CreateQueue(int Capacity)
{
    Queue Q = malloc(sizeof(*Q));
    if (!Q)
        FatalError("Out of space");
    if (Capacity < MinQueueSize)
        FatalError("Capacity too small");
    Q->Array = malloc(sizeof(*Q->Array) * Capacity);
    Q->Capacity = Capacity;
    MakeEmpty(Q);
    return Q;
}

void DisposeQueue(Queue Q)
{
    if (Q)
    {
        free(Q->Array);
        free(Q);
    }
}

void Enqueue(ElementType X, Queue Q)
{
    int index = 0;
    if (IsFull(Q))
        FatalError("Queue is full");
    index = (Q->Rear + 1) % Q->Capacity;
    Q->Rear = index;
    Q->Array[Q->Rear] = X;
    Q->Size++;
}

ElementType Front(Queue Q)
{
    if (IsEmpty(Q))
        FatalError("Queue is empty");
    else
        return Q->Array[Q->Front];
}

void Dequeue(Queue Q)
{
    if (IsEmpty(Q))
        FatalError("Queue is empty");
    else
    {
        int index = 0;
        index = (Q->Front + 1) % Q->Capacity;
        Q->Front = index;
        Q->Size--;
    }
}

ElementType FrontAndDequeue(Queue Q)
{
    if (IsEmpty(Q))
        FatalError("Queue is empty");
    else
    {
        int index = 0;
        int tmp = Q->Array[Q->Front];
        index = (Q->Front + 1) % Q->Capacity;
        Q->Front = index;
        Q->Size--;
        return tmp;
    }
}